package com.hzy.utils;

import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.audience.AudienceTarget;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.hzy.constant.ConfigConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 极光推送
 */
public class Jpush {
    private static final Logger LOG = LoggerFactory.getLogger(Jpush.class);

    private static final String TITLE = "快乐众";
    private static final String ALERT = "祝大家新春快乐";
    private static final String MSG_CONTENT = "申通快递祝新老客户新春快乐";

    public static void main(String[] args) {
//        Jpush.sendPush("111", "测试服务器推送", 1, "120c83f7609db801f96");
        Jpush.sendPush(Arrays.asList("160a3797c8bd36710d7".split(",")), "11111111", null, "548107e13dec8ff41157872b", "db2056ce7779533b94578225");
//        Jpush.sendPush(Arrays.asList("120c83f7609db801f96".split(",")), "申通快递祝新老客户新春快乐", null, "548107e13dec8ff41157872b", "db2056ce7779533b94578225");
//        Jpush.sendPush(Arrays.asList("120c83f7609db801f96".split(",")), "申通快递祝新老客户新春快乐", null, "94cb6ffcec4dad06db925a63", "641fd03e2f7bac00a72f67c6");
    }
    /**
     * 推送指定内容到指定单用户
     *
     * @param content 推送内容
     * @param type    类型
     * @param userId  用户id
     */
    public static void sendPush(String objectId, String content, int type, String userId) {
        JPushClient jpushClient = new JPushClient(ConfigConstants.JPush.J_PUSH_MASTER_SECRET, ConfigConstants.JPush.J_PUSH_APP_KEY, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObjectAndroidIOSAliasAlert(userId, content, type, objectId);
        execute(jpushClient, payload);
    }

    /**
     * 推送指定内容到指定一批用户
     *
     * @param objectId      对应内容id
     * @param userId  用户id
     * @param content 推送内容
     * @param type    类型
     */
    public static void sendPush(String objectId, String content, int type, List<String> userId) {
        JPushClient jpushClient = new JPushClient(ConfigConstants.JPush.J_PUSH_MASTER_SECRET, ConfigConstants.JPush.J_PUSH_APP_KEY, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObject_ios_audienceMore_messageWithExtras(content, type, objectId, userId);
        execute(jpushClient, payload);
    }

    /**
     * 推送指定内容到指定一批用户
     *
     * @param userId  用户id
     * @param content 推送内容
     * @param param   扩展字段内容
     */
    public static void sendPush(List<String> userId, String content, Map<String, String> param) {
        JPushClient jpushClient = new JPushClient(ConfigConstants.JPush.J_PUSH_MASTER_SECRET, ConfigConstants.JPush.J_PUSH_APP_KEY, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObject_ios_audienceMore_messageWithExtras(userId, content, param);
        execute(jpushClient, payload);
    }


    /**
     * 推送给别名的iOS用户对应内容，推送打印信息
     */
    public static void sendPush(List<String> userId, Map<String, String> param, String masterSecret, String appKey) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObjectIOSWmAliasAlert(userId, param);
        execute(jpushClient, payload);
    }

    /**
     * 通用推送，向特定服务器中 指定某批用户继续推送
     *
     * @param userId  用户id
     * @param content 推送内容
     * @param param   扩展字段内容
     */
    public static void sendPush(List<String> userId, String content, Map<String, String> param, String masterSecret, String appKey) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObject_wm_audienceMore_messageWithExtras(userId, content, param);
        execute(jpushClient, payload);
    }

    /**
     * 推送自定义消息 指定内容到指定一批用户
     *
     * @param userId  用户id
     * @param content 推送内容
     * @param param   扩展字段内容
     */
    public static void sendSelfPush(List<String> userId, String content, Map<String, String> param) {
        JPushClient jpushClient = new JPushClient(ConfigConstants.JPush.J_PUSH_MASTER_SECRET, ConfigConstants.JPush.J_PUSH_APP_KEY, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObject_ios_audienceMore_self_messageWithExtras(userId, content, param);
        execute(jpushClient, payload);
    }

    public static void sendSelfPush(List<String> userId, String content, Map<String, String> param, String masterSecret, String appKey) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObject_ios_audienceMore_self_messageWithExtras(userId, content, param);
        execute(jpushClient, payload);
    }


    /**
     * 推送自定义消息 指定内容 广播到 所有用户
     *
     * @param content 推送内容
     * @param param   扩展字段内容
     */
    public static void sendSelfPushAllUser(String content, Map<String, String> param) {
        JPushClient jpushClient = new JPushClient(ConfigConstants.JPush.J_PUSH_MASTER_SECRET, ConfigConstants.JPush.J_PUSH_APP_KEY, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObject_ios_audienceMore_self_messageWithExtras_all_user(content, param);
        execute(jpushClient, payload);
    }

    /**
     * 推送指定内容到指定一批用户
     *
     * @param userId  用户id列表
     * @param content 推送内容
     * @param objectId 动态id
     * @param type    通知类型
     * @param status  0普通动态  1动态
     * @param iconUrl 图片地址
     */
    public static void sendPush(List<String> userId, String content, String objectId, int type, int status, String iconUrl) {
        JPushClient jpushClient = new JPushClient(ConfigConstants.JPush.J_PUSH_MASTER_SECRET, ConfigConstants.JPush.J_PUSH_APP_KEY, null, ClientConfig.getInstance());
        //生成推送的内容，这里我们先测试全部推送
        PushPayload payload = buildPushObject_ios_audienceMore_messageWithExtras(userId, content, objectId, type, status, iconUrl);
        execute(jpushClient, payload);
    }

    // ------------------------------------------------------ 分隔线 ------------------------------------------------------ ---------------


    /**
     * 推送给别名的iOS用户对应内容，推送打印信息
     *
     *
     * @return 返回推送内容
     */
    public static PushPayload buildPushObjectIOSWmAliasAlert(List<String> userId, Map<String, String> param) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())  //推送平台设置
                .setAudience(Audience.registrationId(userId))
                .setNotification(Notification
                        .newBuilder()
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert("")
                                .addExtras(param)
                                .setContentAvailable(true)
                                .setMutableContent(true)
                                .setSound("")
                                .build())
                        .build())    //通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存
                .setOptions(Options.newBuilder().setApnsProduction(false).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }


    /**
     * 向多用户发送通知
     *
     * @param userId  用户id列表
     * @param content 消息内容
     * @param param   扩展字段内容
     *
     * @return 返回推送内容
     */
    public static PushPayload buildPushObject_wm_audienceMore_messageWithExtras(List<String> userId, String content,
                                                                                Map<String, String> param) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())  //推送平台设置
//                        .setAudience(Audience.newBuilder()
//                                .addAudienceTarget(AudienceTarget
//                                        .registrationId(userId))
                        .setAudience(Audience.registrationId(userId))
                .setNotification(Notification
                        .newBuilder()
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setTitle(TITLE)
                                .setAlert(content)
                                .addExtras(param)
                                .build())
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(content)
                                .addExtras(param)
                                .setContentAvailable(true)
                                .setMutableContent(true)
                                .setSound("default")

                                .build())
                        .build())    //通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存
                .setOptions(Options.newBuilder().setApnsProduction(true).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }


    private static PushPayload buildPushObject_ios_audienceMore_messageWithExtras(List<String> userId, String content,
                                                                                  String objectId, int type, int status, String iconUrl) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.android_ios())  //推送平台设置
                .setAudience(Audience.newBuilder()
                        .addAudienceTarget(AudienceTarget
                                .registrationId(userId))
                        .build())
                .setNotification(Notification
                        .newBuilder()
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setTitle(TITLE)
                                .addExtra("type", type)
                                .addExtra("objectId", objectId)
                                .addExtra("status", status)
                                .setLargeIcon(iconUrl)
                                .setAlert(content).
                                        build())
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(content)
                                .addExtra("type", type)
                                .addExtra("objectId", objectId)
                                .addExtra("status", status)
                                .build())
                        .build())    //通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存
                .setOptions(Options.newBuilder().setApnsProduction(true).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }


    private static void execute(JPushClient jpushClient, PushPayload payload) {
        try {
            System.out.println(payload.toString());
            PushResult result = jpushClient.sendPush(payload);
            System.out.println(result + "................................");
            LOG.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOG.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            LOG.error("Error response from JPush server. Should review and fix it. ", e);
            LOG.info("HTTP Status: " + e.getStatus());
            LOG.info("Error Code: " + e.getErrorCode());
            LOG.info("Error Message: " + e.getErrorMessage());
            LOG.info("Msg ID: " + e.getMsgId());
        }
    }

    /**
     * 推送给置顶别名的Android和iOS用户对应内容
     * @return 返回推送内容
     */
    public static PushPayload buildPushObjectAndroidIOSAliasAlert(String userId, String content, int type, String objectId) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())  //推送平台设置
                .setAudience(Audience.registrationId(userId))
                .setNotification(Notification
                        .newBuilder()
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setTitle(TITLE)
                                .addExtra("type", type)
                                .addExtra("objectId", objectId)
                                .setAlert(content)
                                .build())
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(content)
                                .addExtra("type", type)
                                .addExtra("objectId", objectId)
                                .setSound("default")
                                .build())
                        .build())    //通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存
                .setOptions(Options.newBuilder().setApnsProduction(true).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }

    /**
     * 向多用户发送通知
     *
     * @param content 内容
     * @param type    类型
     * @param objectId      对应内容id
     * @param userId  用户id
     *
     * @return 返回推送内容
     */
    public static PushPayload buildPushObject_ios_audienceMore_messageWithExtras(String content, int type,
                                                                                 String objectId, List<String> userId) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())  //推送平台设置

                .setAudience(Audience.newBuilder()
                        .addAudienceTarget(AudienceTarget
                                .registrationId(userId))
                        .build())
                .setNotification(Notification
                        .newBuilder()
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setTitle(TITLE)
                                .addExtra("type", type)
                                .addExtra("objectId", objectId)
                                .setAlert(content)
                                .build())
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(content)
                                .addExtra("type", type)
                                .addExtra("objectId", objectId)
                                .setSound("default")
                                .build())
                        .build())    //通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存
                .setOptions(Options.newBuilder().setApnsProduction(true).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }

    /**
     * 向多用户发送通知
     *
     * @param userId  用户id列表
     * @param content 消息内容
     * @param param   扩展字段内容
     *
     * @return 返回推送内容
     */
    public static PushPayload buildPushObject_ios_audienceMore_messageWithExtras(List<String> userId, String content,
                                                                                 Map<String, String> param) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())  //推送平台设置
                .setAudience(Audience.newBuilder()
                        .addAudienceTarget(AudienceTarget
                                .registrationId(userId))
                        .build())
                .setNotification(Notification
                        .newBuilder()
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setTitle(TITLE)
                                .setAlert(content)
                                .addExtras(param)
                                .build())
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(content)
                                .addExtras(param)
                                .setSound("default")

                                .build())
                        .build())    //通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存
                .setOptions(Options.newBuilder().setApnsProduction(true).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }

    /**
     * 向多用户发送自定义消息
     *
     * @param userId  用户id列表
     * @param content 消息内容
     * @param param   扩展字段内容
     *
     * @return 返回推送内容
     */
    public static PushPayload buildPushObject_ios_audienceMore_self_messageWithExtras(List<String> userId, String content,
                                                                                      Map<String, String> param) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())  //推送平台设置
                .setAudience(Audience.newBuilder()
                        .addAudienceTarget(AudienceTarget
                                .registrationId(userId))
                        .build())
                .setMessage(Message.newBuilder().setMsgContent(content)
                        .addExtras(param)
                        .build())
                .setOptions(Options.newBuilder().setApnsProduction(true).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }

    /**
     * 向多用户发送自定义消息
     *
     * @param content 消息内容
     * @param param   扩展字段内容
     *
     * @return 返回推送内容
     */
    public static PushPayload buildPushObject_ios_audienceMore_self_messageWithExtras_all_user(String content,
                                                                                               Map<String, String> param) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())  //推送平台设置
                .setAudience(Audience.newBuilder().setAll(true)
//                        .addAudienceTarget(AudienceTarget
//                                .registrationId(userId))
                        .build())
                .setMessage(Message.newBuilder().setMsgContent(content)
                        .addExtras(param)
                        .build())
                .setOptions(Options.newBuilder().setApnsProduction(true).build()) //短信渠道补充送达内容体
                //.setCid() //	用于防止 api 调用端重试造成服务端的重复推送而定义的一个标识符。
                .build();
    }
}